#!/usr/bin/env python
# coding=UTF-8
"""
Copyright Ian Ross Williams, 2012

    This file is part of ArcSecond.

    ArcSecond is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    ArcSecond is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with ArcSecond.  If not, see <http://www.gnu.org/licenses/>.
"""
import pygtk
pygtk.require('2.0')
import gtk.gdk
import gobject
#Prepare for threading
gobject.threads_init()

import time
import numpy as np
import os
import Image

#Import the other modules of this program
from arcsecond import notebook_register
from arcsecond import notebook_view_stack
from arcsecond import notebook_stack
from arcsecond import notebook_deconvolution

initialPath = None
#initialPath = "/home/ian/Code/PSF_SVD"
#initialPath = "/home/ian/ATM/8inch/Star Testing/13thJan2012/Jupiter/jupiter_20120112/registered"
#initialPath = "/home/ian/ATM/8inch"
#initialPath = "/home/wi10008/Code/gtkapture/gtkapture/src"
#initialPath = "/home/ian/workspace/gtkapture/src"
#initialPath = "/home/ian/Code/gtkapture/src"

class ArcSecondWindow(gtk.Window):
    notebook_register = None
    notebook_view_stack = None
    
    (
    PAGE_REGISTER,
    PAGE_VIEW,
    PAGE_STACK,
    PAGE_DECONVOLVE
    ) = range(4)
    
    ui_string = """<ui>
      <menubar name='Menubar'>
        <menu action='FileMenu'>
          <menuitem action='New'/>
          <separator/>
          <menuitem action='Open image'/>
          <menuitem action='Save image'/>
          <separator/>
          <menuitem action='Open PSF'/>
          <menuitem action='Save PSF'/>
          <menuitem action='Exit'/>
        </menu>
        <menu action='HelpMenu'>
          <menuitem action='About'/>
        </menu>
      </menubar>
    </ui>"""

    def file_new(self, widget, data=None):
        self.notebook_stack.new()

    # Open an image for post-processing
    def file_open(self, widget, data=None):
        self.notebook_deconvolve.load_image()
        
    # Open a PSF to use for deconvolution
    def file_open_psf(self, widget, data=None):
        self.notebook_deconvolve.load_psf()

    # Open a PSF to use for deconvolution
    def file_save_psf(self, widget, data=None):
        self.notebook_deconvolve.save_psf()

    def file_save(self, widget, data=None):
        page=self.notebook.get_current_page()
        if page==self.PAGE_VIEW:
            im=self.notebook_view_stack.image
        elif page==self.PAGE_STACK:
            im=self.notebook_stack.image
        elif page==self.PAGE_DECONVOLVE:
            im=self.notebook_deconvolve.imageProcessed
            if not im:
                im=self.notebook_deconvolve.image 
        
        if im:
            imageDlg = gtk.FileChooserDialog(
                title="Save image",
                action=gtk.FILE_CHOOSER_ACTION_SAVE,
                buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_SAVE,gtk.RESPONSE_OK))
            imageDlg.set_default_response(gtk.RESPONSE_CANCEL)
            filter = gtk.FileFilter()
            filter.set_name("Images")
            filter.add_mime_type("image/png")
            filter.add_mime_type("image/ppm")
            filter.add_mime_type("image/jpeg")
            filter.add_mime_type("image/gif")
            filter.add_mime_type("image/bmp")
            filter.add_mime_type("image/psd")
            filter.add_pattern("*.png")
            filter.add_pattern("*.jpg")
            filter.add_pattern("*.gif")
            filter.add_pattern("*.bmp")
            filter.add_pattern("*.xbm")
            filter.add_pattern("*.tif")
            filter.add_pattern("*.xpm")
            filter.add_pattern("*.psd")
            imageDlg.add_filter(filter)
    
            filter = gtk.FileFilter()
            filter.set_name("All files")
            filter.add_pattern("*")
            imageDlg.add_filter(filter)
    
            response = imageDlg.run()
            if response == gtk.RESPONSE_OK:
                filename = imageDlg.get_filename()
                if im.mode=="F": 
                    nim=np.asarray(im)*255
                    im=Image.fromarray(nim)
                    im=im.convert("I")
                
                try:
                    im.save(filename)
                except IOError:
                    msg= "Could not save image."
                    print msg
                    self.statusbar.pop(self.statusbarID)
                    self.statusbar.push(self.statusbarID,msg)
                
            imageDlg.destroy()
            
    # Open a new capture project
    def file_exit(self, widget, data=None):        
        #Tell gtk to stop its main loop and exit
        gtk.main_quit()

    def notebook_switch(self, notebook, page, page_num):
        #Make sure to de-select the capture notebook before doing anything else
        if page_num==self.PAGE_REGISTER:
            ROI = self.notebook_view_stack.get_ROI()
            self.notebook_register.selected(ROI)
            
        elif page_num==self.PAGE_VIEW:
            frameList = self.notebook_register.get_frame_list()
            self.notebook_view_stack.set_frames(frameList)
            
        elif page_num==self.PAGE_STACK:
            frameEnabled = self.notebook_register.get_frame_enabled()
            frameList    = self.notebook_register.get_frame_list()
            shift        = self.notebook_register.get_frame_shifts()
            fl=np.array([])
            fs=np.array([])
            for i,e in enumerate(frameEnabled):
                if e:
                    print i,frameList[i]
                    fl=np.append(fl,frameList[i])
                    fs=np.append(fs,shift[i])
            self.notebook_stack.set_frames(fl, fs)
            self.notebook_stack.selected()
            
        elif page_num==self.PAGE_DECONVOLVE:
            image = self.notebook_stack.image
            if image:
                self.notebook_deconvolve.image = image
    
    def keyboard_callback(self, window, event):
        keyval = event.keyval
        name = gtk.gdk.keyval_name(keyval)
        page = self.notebook.get_current_page()
        if name=="Delete" and page==self.PAGE_REGISTER: 
            self.notebook_register.buttonRemove.activate()
        elif name=="Escape" and (page==self.PAGE_REGISTER or page==self.PAGE_VIEW):
                self.notebook_register.clear_ROI()
                self.notebook_view_stack.clear_ROI()
        elif name=="Escape" and self.notebook.get_current_page()==self.PAGE_STACK: 
            self.notebook_stack.clear_roi()
        elif name=="Escape" and self.notebook.get_current_page()==self.PAGE_DECONVOLVE: 
            self.notebook_deconvolve.clear_psf()
            
    def create_ui(self):        
        ag = gtk.ActionGroup('WindowActions')
        actions = [
            ('FileMenu', None, '_File'),
            ('New', gtk.STOCK_NEW, '_New', '<control>N', 'Clear the result image', self.file_new),
            ('Open image', gtk.STOCK_OPEN, '_Open image', '<control>O', 'Open an image for post-processing', self.file_open),
            ('Save image', gtk.STOCK_SAVE, '_Save image', '<control>S', 'Save the current image to file', self.file_save),
            ('Open PSF', None, 'Open PS_F', None, 'Open a point spread function to use for deconvolution', self.file_open_psf),
            ('Save PSF', None, 'Sa_ve PSF', None, 'Save the current point spread function to file', self.file_save_psf),
            ('Exit',     gtk.STOCK_QUIT, 'E_xit', '<control>Q', 'Close the program', self.file_exit),
            ('HelpMenu', None, '_Help'),
            ('About',    None, '_About', None, 'About application', None)
            ]
        ag.add_actions(actions)
        
        self.ui = gtk.UIManager()
        self.ui.add_ui_from_string(self.ui_string)
        self.ui.insert_action_group(ag, 0)
        self.add_accel_group(self.ui.get_accel_group())

        # Pack the main window vertically with a menu, notebook and status-bar
        vbox = gtk.VBox()
        vbox.set_border_width(1)
        self.add(vbox)
                
        # Add a status bar to the bottom of the window
        hboxStatus = gtk.HBox()
        self.statusbar = gtk.Statusbar()
        self.statusbarID = self.statusbar.get_context_id("Frames captured")
        hboxStatus.pack_start(self.statusbar,True,True,0)
        self.statusbar.show()
        vbox.pack_end(hboxStatus,expand=False, fill=False, padding=0)
        hboxStatus.show()
        
        # Create the tabbed notebook
        self.notebook = gtk.Notebook()
        self.notebook.set_tab_pos(gtk.POS_TOP)
        
        # Add the pages
        label = gtk.Label("Register")
        self.notebook_view_stack = notebook_view_stack.notebook_view_stack(self.statusbar, self.statusbarID)
        self.notebook_register = notebook_register.notebook_register(self.notebook,self.notebook_view_stack,self.statusbar, self.statusbarID, self.PAGE_VIEW)
        page = self.notebook_register.get_page()
        self.notebook.append_page(page, label)
        
        label = gtk.Label("Frames")
        page = self.notebook_view_stack.get_page()
        self.notebook.append_page(page, label)

        label = gtk.Label("Stack")
        self.notebook_stack = notebook_stack.notebook_stack(self.statusbar, self.statusbarID)
        page = self.notebook_stack.get_page()
        self.notebook.append_page(page, label)
        
        label = gtk.Label("Deconvolve")
        self.notebook_deconvolve = notebook_deconvolution.notebook_deconvolution(self.statusbar, self.statusbarID)
        page = self.notebook_deconvolve.get_page()
        self.notebook.append_page(page, label)

        # Connect the keyboard call-back
        self.connect("key-press-event",self.keyboard_callback)

        # Put the menu bar at the top of the window
        vbox.pack_start(self.ui.get_widget('/Menubar'), expand=False)
        vbox.pack_start(self.notebook,expand=True, fill=True, padding=0)
        self.notebook.connect('switch-page', self.notebook_switch)
        self.notebook.show()
        
        #The main window vbox is now populated 
        vbox.show()
    
    def __init__(self):
        if initialPath: os.chdir(initialPath)
        
        # Create a new window
        gtk.Window.__init__(self)
        self.set_default_size(640,480)
        self.set_title("ArcSecond")
        self.set_position(gtk.WIN_POS_CENTER)
        self.maximize()        
        
        # Handle the delete event.
        self.connect("delete_event", self.file_exit)
        
        # Create the user interface
        self.create_ui()

        # The window is ready to go.
        self.show()

if __name__ == "__main__":
    gtkaptureWindow = GTKaptureWindow()
    with gtk.gdk.lock:  #Start the code with a thread lock
        gtk.main()
